<?php
// +----------------------------------------------------------------------
// | [KyPHP System] Copyright (c) 2020 http://www.kuryun.com/
// +----------------------------------------------------------------------
// | [KyPHP] 并不是自由软件,你可免费使用,未经许可不能去掉KyPHP相关版权
// +----------------------------------------------------------------------
// | Author: fudaoji <fdj@kuryun.cn>
// +----------------------------------------------------------------------
/**
 * Created by PhpStorm.
 * Script Name: Templatemsg.php
 * Create: 2020/6/10 17:23
 * Description: 模版消息
 * Author: fudaoji<fdj@kuryun.cn>
 */
namespace app\mp\controller;

use app\admin\controller\FormBuilder;
use app\common\model\MpTemplatemsg;
use app\common\model\MpTemplatemsgTask;
use app\mp\controller\handler\mp\MessageObj;

class Templatemsg extends Base
{
    /**
     * @var  MpTemplatemsg
     */
    private $msgM;
    /**
     * @var array
     */
    private $tabs;
    /**
     * @var MpTemplatemsgTask
     */
    private $taskM;

    public function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub
        $this->msgM = new MpTemplatemsg();
        $this->taskM = new MpTemplatemsgTask();
        $this->tabs = [
            'task' => ['title' => '任务列表', 'href' => url('task')],
            'index' => ['title' => '消息列表', 'href' => url('index')],
            'templates' => ['title' => '模板列表', 'href' => url('templates')]
        ];
    }

    /**
     * 编辑
     * @return mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function edit(){
        $id = input('id');
        $data = $this->msgM->getOne($id);
        if(empty($data)){
            $this->error('数据不存在');
        }
        if(request()->isPost()){
            $post_data = input('post.');
            $res = $this->validate($post_data,'MpTemplatemsg');

            if($res !== true){
                $this->error($res, '', ['token' => request()->token()]);
            }
            $content = [];
            foreach ($post_data as $k => $p){
                if(strpos($k, '{{') === 0){
                    $content[str_replace(['{{', "_DATA", '}}'], ['','',''], $k)] = [
                        'value' => $p,
                        'color' => $post_data['color_'.$k]
                    ];
                }
            }
            $data = [
                'id' => $post_data['id'],
                'title' => $post_data['title'],
                'url' => $post_data['url'],
                'content' => json_encode($content, JSON_UNESCAPED_UNICODE),
                'preview' => $post_data['preview'] ?: ''
            ];

            if($this->msgM->updateOne($data)){
                $this->success('保存成功', url('index'));
            }else{
                $this->error('保存失败，请刷新重试', '', ['token' => request()->token()]);
            }
        }
        $data_list = $this->pullTemplates();
        $template = [];
        foreach ($data_list as $item){
            if($item['template_id'] == $data['template_id']){
                $template = $item;
                break;
            }
        }
        preg_match_all("/(\{\{.*\}\})/", $template['content'], $keywords);
        $keywords = $keywords[0];
        $content = json_decode($data['content'], true);
        foreach ($keywords as $k => $v){
            $r = str_replace(['{{', ".DATA", '}}'], ['','',''], $v);
            if(isset($content[$r])){
                $content[$r]['key'] = $v;
                $template['content'] = str_replace($v, '<span style="color:'.$content[$r]['color'].'">'.$content[$r]['value'].'</span>', $template['content']);
            }
        }
        //dump($content);exit;
        $builder = new FormBuilder();
        $builder->addFormItem('id', 'hidden', 'id', 'id')
            ->addFormItem('title', 'text', '标题', '消息标题，50字符内', [], 'required maxlength=50')
            ->addFormItem('url', 'text', '跳转链接', '跳转链接', [], ' maxlength=200')
            ->setFormData($data)
            ->setTemplate('templatemsg/edit');
        $assign = [
            'template' => $template,
            'keywords' => $content,
        ];
        return $builder->show($assign);
    }

    /**
     * 新增消息
     * @return mixed
     * @throws \think\Exception
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function add(){
        if(request()->isPost()){
            $post_data = input('post.');
            $res = $this->validate($post_data,'MpTemplatemsg');

            if($res !== true){
                $this->error($res, '', ['token' => request()->token()]);
            }
            $content = [];
            foreach ($post_data as $k => $p){
                if(strpos($k, '{{') === 0){
                    $content[str_replace(['{{', "_DATA", '}}'], ['','',''], $k)] = [
                        'value' => $p,
                        'color' => $post_data['color_'.$k]
                    ];
                }
            }
            $data = [
                'mpid' => $this->mpId,
                'template_id' => $post_data['template_id'],
                'title' => $post_data['title'],
                'url' => $post_data['url'],
                'content' => json_encode($content, JSON_UNESCAPED_UNICODE),
                'preview' => $post_data['preview'] ?: ''
            ];
            if($this->msgM->addOne($data)){
                $this->success('保存成功', url('index'));
            }else{
                $this->error('保存失败，请刷新重试', '', ['token' => request()->token()]);
            }
        }
        $data_list = $this->pullTemplates();
        $template = [];
        foreach ($data_list as $item){
            if($item['template_id'] == input('template_id')){
                $template = $item;
                break;
            }
        }
        if(empty($template)){
            $this->error('参数错误');
        }
        preg_match_all("/(\{\{.*\}\})/", $template['content'], $keywords);

        $builder = new FormBuilder();
        $builder->addFormItem('template_id', 'hidden', 'template_id', 'template_id')
            ->addFormItem('title', 'text', '标题', '消息标题，50字符内', [], 'required maxlength=50')
            ->addFormItem('url', 'text', '跳转链接', '跳转链接', [], ' maxlength=200')
            ->setFormData($template)
            ->setTemplate('templatemsg/add');
        $assign = [
            'template' => $template,
            'keywords' => $keywords[0]
        ];
        return $builder->show($assign);
    }

    /**
     * 模版列表
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     * @throws \think\exception\DbException
     */
    public function templates(){
        $data_list = $this->pullTemplates();
        $assign = [
            'data_list' => $data_list,
            'tabs' => $this->tabs,
            'tab' => __FUNCTION__
        ];
        return $this->show($assign);
    }

    /**
     * 消息列表
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     * @throws \think\exception\DbException
     */
    public function index(){
        $where = ['mpid' => $this->mpId];
        $search_key = input('search_key', '');
        $search_key && $where['title'] = ['like', '%'.$search_key.'%'];

        $data_list = $this->msgM->page($this->pageSize, $where, ['id' => 'desc'], true, 1);
        $page = $data_list->appends(['search_key' => $search_key])->render();
        $assign = [
            'data_list' => $data_list,
            'page' => $page,
            'search_key' => $search_key,
            'tabs' => $this->tabs,
            'tab' => __FUNCTION__
        ];
        return $this->show($assign);
    }

    private function pullTemplates(){
        $data_list = $this->mpApp->template_message->getPrivateTemplates();
        if(isset($data_list['template_list'])){
            $data_list = $data_list['template_list'];
        }else{
            $data_list = [];
        }
        return $data_list;
    }

    /**
     * 推送任务
     * @return mixed
     * @throws \think\exception\DbException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function task(){
        $where = ['task.mpid' => $this->mpId];
        if(!empty($msg_id = input('msg_id'))){
            $where['msg.id'] = $msg_id;
        }
        $search_key = input('search_key', '');
        $search_key && $where['msg.title'] = ['like', '%'.$search_key.'%'];

        $data_list = $this->taskM->pageJoin([
            'alias' => 'task',
            'join' => [
                ['mp_templatemsg msg', 'msg.id=task.templatemsg_id']
            ],
            'page_size' => $this->pageSize,
            'where' => $where,
            'order' => ['task.id' => 'desc'],
            'refresh' => true,
            'field' => ['task.*', 'msg.title as msg_title']
        ]);
        $page = $data_list->appends(['search_key' => $search_key])->render();
        $redis = controller('common/base', 'event')->getRedis();
        foreach ($data_list as $k => $v){
            $v['count'] = $redis->get('tempmsg_count_'.$v['id']) ?: $v['count'];
            $data_list[$k] = $v;
        }
        $assign = [
            'data_list' => $data_list,
            'page' => $page,
            'search_key' => $search_key,
            'tabs' => $this->tabs,
            'tab' => __FUNCTION__,
            'status_list' => MpTemplatemsgTask::statusList()
        ];
        return $this->show($assign);
    }

    /**
     * 新增任务
     * @return mixed
     * @throws \think\Exception
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function taskAdd(){
        $msg_list = $this->msgM->getFieldByOrder([
            'field' => ['id,title'],
            'where' => ['status' => 1, 'mpid' => $this->mpId],
            'order' => ['id' => 'desc']
        ]);
        $builder = new FormBuilder();
        $builder->setTemplate('common/form')
            ->setPostUrl(url('tasksavepost'))
            ->addFormItem('templatemsg_id', 'select', '选择消息', '选择消息', $msg_list, 'required')
            ->addFormItem('title', 'text', '任务名称', '50字符内', [], 'required maxlength=50')
            ->addFormItem('push_time', 'datetime', '推送时间', '不填则立即推送');
        return $builder->show();
    }

    /**
     * 编辑任务
     * @return mixed
     * @throws \think\Exception
     * @author: fudaoji<fdj@kuryun.cn>
     */
    public function taskEdit(){
        if(! $data = $this->taskM->getOne(input('id'))){
            $this->error('数据不存在');
        }
        if($data['status'] != 0){
            $this->error('此任务禁止修改');
        }
        $msg_list = $this->msgM->getFieldByOrder([
            'field' => ['id,title'],
            'where' => ['status' => 1, 'mpid' => $this->mpId],
            'order' => ['id' => 'desc']
        ]);
        $builder = new FormBuilder();
        $builder->setTemplate('common/form')
            ->setTip("只有在任务未开始前才能修改")
            ->setPostUrl(url('tasksavepost'))
            ->addFormItem('id', 'hidden', 'id', 'id')
            ->addFormItem('templatemsg_id', 'select', '选择消息', '选择消息', $msg_list, 'required')
            ->addFormItem('title', 'text', '任务名称', '50字符内', [], 'required maxlength=50')
            ->addFormItem('push_time', 'datetime', '推送时间', '不填则立即推送')
            ->setFormData($data);
        return $builder->show();
    }

    /**
     * 任务保存
     * @throws \think\Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function taskSavePost(){
        if(request()->isPost()){
            $post_data = input('post.');
            $res = $this->validate($post_data,'MpTemplatemsgTask');

            if($res !== true){
                $this->error($res, '', ['token' => request()->token()]);
            }

            $post_data['mpid'] = $this->mpId;
            if(empty($post_data['push_time'])){
                $post_data['push_time'] = time();
            }else{
                $post_data['push_time'] = strtotime($post_data['push_time']);
            }
            $wx_res = $this->mpApp->user->list('');
            if(!empty($wx_res['total'])){
                $post_data['total'] = $wx_res['total'];
            }
            if(empty($post_data['id'])){
                $res = $this->taskM->addOne($post_data);
            }else{
                $res = $this->taskM->updateOne($post_data);
            }
            if($res){
                controller('common/TaskQueue', 'event')->push([
                    'delay' => max(1, $res['push_time'] - time()),
                    'params' => [
                        'do' => ['\\app\\mp\\event\\Templatemsg', 'task'],
                        'task_id' => $res['id'],
                        'delay' => 1,
                        'interval' => 3000, //5秒
                        'step' => 500, //每interval秒执行step次
                    ]
                ]);
                $this->success('保存成功', url('task'));
            }else{
                $this->error('保存失败，请刷新重试', '', ['token' => request()->token()]);
            }
        }
    }

    /**
     * 停止任务
     * @throws \think\Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function taskStopPost()
    {
        if (request()->isPost()) {
            $post_data = input('post.');
            $task = $this->taskM->getOne($post_data['id']);
            if($task && $task['status'] == 3){
                $this->error('此任务不存在或已终止', '', ['token' => request()->token()]);
            }
            $this->taskM->updateOne([
                'id' => $task['id'],
                'status' => 3
            ]);
            $this->success('操作成功！');
        }
    }
}